export const tintColor = (color, tint) => {
  color = color.charAt(0) === '#' ? color.slice(1) : color
  let red = parseInt(color.slice(0, 2), 16)
  let green = parseInt(color.slice(2, 4), 16)
  let blue = parseInt(color.slice(4, 6), 16)

  if (tint === 0) { // when primary color is in its rgb space
    return [red, green, blue].join(',')
  } else {
    red += Math.round(tint * (255 - red))
    green += Math.round(tint * (255 - green))
    blue += Math.round(tint * (255 - blue))

    red = red.toString(16)
    green = green.toString(16)
    blue = blue.toString(16)

    red = red.padStart(2, '0')
    green = green.padStart(2, '0')
    blue = blue.padStart(2, '0')

    return `#${red}${green}${blue}`
  }
}

export const shadeColor = (color, shade) => {
  color = color.charAt(0) === '#' ? color.slice(1) : color
  let red = parseInt(color.slice(0, 2), 16)
  let green = parseInt(color.slice(2, 4), 16)
  let blue = parseInt(color.slice(4, 6), 16)

  red = Math.round((1 - shade) * red)
  green = Math.round((1 - shade) * green)
  blue = Math.round((1 - shade) * blue)

  red = red.toString(16)
  green = green.toString(16)
  blue = blue.toString(16)

  red = red.padStart(2, '0')
  green = green.padStart(2, '0')
  blue = blue.padStart(2, '0')

  return `#${red}${green}${blue}`
}

export function getThemeCluster (theme) {
  const clusters = [theme]
  for (let i = 0; i <= 9; i++) {
    clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
  }
  clusters.push(shadeColor(theme, 0.1))
  return clusters
}

function updateStyle (style, oldCluster, newCluster) {
  let newStyle = style.replace(/<\/?.+?>/g, '').replace(/[\r\n]/g, '')
  oldCluster.forEach((color, index) => {
    newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
  })
  return newStyle
}

export default async function changeTheme (val, oldVal) {
  if (!val || !oldVal) return
  const themeCluster = getThemeCluster(val.replace('#', ''))
  const originalCluster = getThemeCluster(oldVal.replace('#', ''))
  const styles = [].slice.call(document.querySelectorAll('style'))
    .filter(style => {
      const text = style.innerText
      return new RegExp(oldVal, 'i').test(text)
    })
  styles.forEach(style => {
    const { innerText } = style
    if (typeof innerText !== 'string') return
    style.innerText = updateStyle(innerText, originalCluster, themeCluster)
  })

  const root = document.documentElement
  root.style.setProperty('--theme-color', val)
  root.style.setProperty('--theme-color-light', tintColor(val, 0.5))
  root.style.setProperty('--theme-color-lighter', tintColor(val, 0.7))
}
